// 导入必要的依赖模块
import { TextBlock } from '../../../vendor/sdk/src/resources' // Anthropic SDK 的文本块类型
import chalk from 'chalk' // 用于终端颜色输出的库
import { last, memoize } from 'lodash-es' // Lodash 工具函数：获取数组最后一个元素和记忆化函数
import { EOL } from 'os' // 操作系统特定的行结束符
import * as React from 'react' // React 库
import { z } from 'zod' // 数据验证库
import { Tool } from '../../Tool.js' // 工具基类
import { FallbackToolUseRejectedMessage } from '../../components/FallbackToolUseRejectedMessage.js' // 工具使用被拒绝时的回退消息组件
import { getAgentPrompt } from '../../constants/prompts.js' // 获取代理提示词
import { getContext } from '../../context.js' // 获取上下文信息
import { hasPermissionsToUseTool } from '../../permissions.js' // 检查工具使用权限
import { AssistantMessage, Message as MessageType, query } from '../../query.js' // 消息类型和查询函数
import { formatDuration, formatNumber } from '../../utils/format.js' // 格式化工具函数
import {
  getMessagesPath,
  getNextAvailableLogSidechainNumber,
  overwriteLog,
} from '../../utils/log.js' // 日志相关工具函数
import { applyMarkdown } from '../../utils/markdown.js' // Markdown 处理工具
import {
  createAssistantMessage,
  createUserMessage,
  getLastAssistantMessageId,
  INTERRUPT_MESSAGE,
  normalizeMessages,
} from '../../utils/messages.js' // 消息处理工具函数
import { getSlowAndCapableModel } from '../../utils/model.js' // 获取慢速但能力强的模型
import { getMaxThinkingTokens } from '../../utils/thinking.js' // 获取最大思考令牌数
import { getAgentTools, getPrompt } from './prompt.js' // 获取代理工具和提示词
import { TOOL_NAME } from './constants.js' // 工具名称常量

// 定义输入数据的验证模式
const inputSchema = z.object({
  prompt: z.string().describe('The task for the agent to perform'), // 代理要执行的任务
})

// 代理工具对象定义
export const AgentTool = {
  // 获取代理提示词
  async prompt({ dangerouslySkipPermissions }) {
    return await getPrompt(dangerouslySkipPermissions)
  },
  
  name: TOOL_NAME, // 工具名称
  
  // 工具描述
  async description() {
    return 'Launch a new task'
  },
  
  inputSchema, // 输入验证模式
  
  // 主要的工具调用函数，使用生成器模式处理流式响应
  async *call(
    { prompt }, // 解构获取提示词
    {
      abortController, // 中止控制器
      options: {
        dangerouslySkipPermissions = false, // 是否跳过权限检查
        forkNumber, // 分支编号
        messageLogName, // 消息日志名称
        verbose, // 详细模式
      },
      readFileTimestamps, // 读取文件时间戳
    },
  ) {
    const startTime = Date.now() // 记录开始时间
    const messages: MessageType[] = [createUserMessage(prompt)] // 初始化消息数组，包含用户消息
    const tools = await getAgentTools(dangerouslySkipPermissions) // 获取代理可用的工具

    // 立即产生初始消息，避免UI在消息开始流式返回时移动
    yield {
      type: 'progress',
      content: createAssistantMessage(chalk.dim('Initializing…')), // 创建初始化消息
      normalizedMessages: normalizeMessages(messages), // 标准化消息
      tools,
    }

    // 并行获取所有必要的配置和上下文
    const [agentPrompt, context, slowAndCapableModel, maxThinkingTokens] =
      await Promise.all([
        getAgentPrompt(), // 获取代理提示词
        getContext(), // 获取上下文
        getSlowAndCapableModel(), // 获取慢速但能力强的模型
        getMaxThinkingTokens(messages), // 获取最大思考令牌数
      ])
    let toolUseCount = 0 // 工具使用计数器

    // 记忆化函数，获取侧链编号，避免重复计算
    const getSidechainNumber = memoize(() =>
      getNextAvailableLogSidechainNumber(messageLogName, forkNumber),
    )

    // 开始查询循环，处理流式消息
    for await (const message of query(
      messages,
      agentPrompt,
      context,
      hasPermissionsToUseTool,
      {
        abortController,
        options: {
          dangerouslySkipPermissions,
          forkNumber,
          messageLogName,
          tools,
          commands: [],
          verbose,
          slowAndCapableModel,
          maxThinkingTokens,
        },
        messageId: getLastAssistantMessageId(messages), // 获取最后一条助手消息的ID
        readFileTimestamps,
      },
    )) {
      messages.push(message) // 将新消息添加到消息数组

      // 覆盖日志文件，记录消息历史
      overwriteLog(
        // 重要：在这里计算侧链编号，避免并发代理保留相同侧链编号的竞态条件
        getMessagesPath(messageLogName, forkNumber, getSidechainNumber()),
        messages.filter(_ => _.type !== 'progress'), // 过滤掉进度消息
      )

      // 如果不是助手消息，继续下一个循环
      if (message.type !== 'assistant') {
        continue
      }

      const normalizedMessages = normalizeMessages(messages) // 标准化消息
      
      // 遍历消息内容，处理工具使用
      for (const content of message.message.content) {
        if (content.type !== 'tool_use') {
          continue
        }

        toolUseCount++ // 增加工具使用计数
        yield {
          type: 'progress',
          content: normalizedMessages.find(
            _ =>
              _.type === 'assistant' &&
              _.message.content[0]?.type === 'tool_use' &&
              _.message.content[0].id === content.id,
          ) as AssistantMessage, // 查找对应的助手消息
          normalizedMessages,
          tools,
        }
      }
    }

    const normalizedMessages = normalizeMessages(messages) // 最终标准化消息
    const lastMessage = last(messages) // 获取最后一条消息
    
    // 验证最后一条消息是助手消息
    if (lastMessage?.type !== 'assistant') {
      throw new Error('Last message was not an assistant message')
    }

    // 检查是否包含中断消息
    if (
      lastMessage.message.content.some(
        _ => _.type === 'text' && _.text === INTERRUPT_MESSAGE,
      )
    ) {
      // 如果包含中断消息，直接输出最后一条消息
      yield {
        type: 'progress',
        content: lastMessage,
        normalizedMessages,
        tools,
      }
    } else {
      // 否则生成完成统计信息
      const result = [
        toolUseCount === 1 ? '1 tool use' : `${toolUseCount} tool uses`, // 工具使用次数
        formatNumber(
          (lastMessage.message.usage.cache_creation_input_tokens ?? 0) +
            (lastMessage.message.usage.cache_read_input_tokens ?? 0) +
            lastMessage.message.usage.input_tokens +
            lastMessage.message.usage.output_tokens,
        ) + ' tokens', // 总令牌数
        formatDuration(Date.now() - startTime), // 执行时间
      ]
      yield {
        type: 'progress',
        content: createAssistantMessage(`Done (${result.join(' · ')})`), // 创建完成消息
        normalizedMessages,
        tools,
      }
    }

    // 输出是AssistantMessage，但由于AgentTool是工具，需要序列化为UserMessage兼容的内容
    const data = lastMessage.message.content.filter(_ => _.type === 'text') // 过滤出文本内容
    yield {
      type: 'result',
      data,
      normalizedMessages,
      resultForAssistant: this.renderResultForAssistant(data), // 为助手渲染结果
      tools,
    }
  },
  
  // 检查是否为只读工具
  isReadOnly() {
    return true // 目前是只读的
  },
  
  // 检查工具是否启用
  async isEnabled() {
    return true
  },
  
  // 用户界面显示的工具名称
  userFacingName() {
    return 'Task'
  },
  
  // 是否需要权限
  needsPermissions() {
    return false
  },
  
  // 为助手渲染结果
  renderResultForAssistant(data) {
    return data
  },
  
  // 渲染工具使用消息
  renderToolUseMessage({ prompt }, { verbose }) {
    const lines = prompt.split(EOL) // 按行分割提示词
    return applyMarkdown(!verbose && lines.length > 1 ? lines[0] + '…' : prompt) // 应用Markdown格式
  },
  
  // 渲染工具使用被拒绝的消息
  renderToolUseRejectedMessage() {
    return <FallbackToolUseRejectedMessage />
  },
} satisfies Tool<typeof inputSchema, TextBlock[]> // 满足Tool接口类型约束
